package com.easy.cloud.web.component.core.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.experimental.UtilityClass;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * 是否使用BeanUtils，很简单，你的数量有上百万吗？你的系统接受不了几十毫秒的延时吗？
 *
 * @author GR
 * @date 2023/10/26 16:02
 */
@UtilityClass
public class BeanUtils {

    /**
     * 属性复制
     *
     * @param source           被copy的对象
     * @param target           新赋值的对象
     * @param ignoreProperties 需过滤的属性
     */
    public void copyProperties(Object source, Object target, String... ignoreProperties) {
        org.springframework.beans.BeanUtils.copyProperties(source, target, ignoreProperties);
    }

    /**
     * 属性复制
     *
     * @param source             被copy的对象
     * @param target             新赋值的对象
     * @param ignoreNullProperty 过滤空属性字段
     * @param ignoreProperties   需过滤的属性
     */
    public void copyProperties(Object source, Object target, boolean ignoreNullProperty, String... ignoreProperties) {
        if (ignoreNullProperty) {
            Set<String> ignorePropertySet = CollUtil.newHashSet(ignoreProperties);
            BeanUtils.putEmptyProperties(source, ignorePropertySet);
            BeanUtils.copyProperties(source, target, ignorePropertySet.toArray(new String[0]));
        } else {
            BeanUtils.copyProperties(source, target, ignoreProperties);
        }
    }

    /**
     * 遍历追加空值属性作为过滤字段
     *
     * @param source            目标对象
     * @param ignorePropertySet 徐过滤字段容器
     */
    public void putEmptyProperties(Object source, Set<String> ignorePropertySet) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(source);
        PropertyDescriptor[] propertyDescriptors = beanWrapper.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            // 已包含，则跳过
            if (ignorePropertySet.contains(propertyDescriptor.getName())) {
                continue;
            }

            // 获取属性值
            Object value = beanWrapper.getPropertyValue(propertyDescriptor.getName());
            // 属性值不为空，则跳过
            if (Objects.nonNull(value) && StrUtil.isNotBlank(value.toString())) {
                continue;
            }

            // 否则追加进过滤字段中
            ignorePropertySet.add(propertyDescriptor.getName());
        }
    }
}
